﻿using System;
using System.Security.Cryptography;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using TwinCAT.Ads;

namespace AdsConnect
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public TcAdsClient adsClient=new TcAdsClient();
        public string NetID = "";
        public int port;

        public MainWindow()
        {
            InitializeComponent();
            cb_plctype.Items.Clear();
            cb_plctype.ItemsSource = Enum.GetValues(typeof(PLCType));
            cb_plctype.SelectedIndex = 0;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                NetID = tb_NetID.Text;
                port = Convert.ToInt16(tb_Port.Text);
                adsClient.Connect(NetID, port);
                connectStatus.Background = Brushes.Green;
                connectStatus.Text = "OK";
            }
            catch (Exception ex)
            {
                Write_rt($"连接失败：\r\n{ex.ToString()}");
                connectStatus.Background = Brushes.Red;
                connectStatus.Text = "Faild";
            }
        }

        private void Write_rt(string text, bool isClear = true)
        { 
            if(isClear)
                rt_info.Document.Blocks.Clear();
            rt_info.Document.Blocks.Add(new Paragraph(new Run(text)));
        }

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            try
            {
                GetPlcValue(tb_address.Text,(PLCType)cb_plctype.SelectedItem);
            }
            catch (Exception ex)
            {
                Write_rt($"读取失败：\r\n{ex.ToString()}");
            }
        }

        private object GetPlcValue(string address, PLCType type)
        {
           var Handel = adsClient.CreateVariableHandle(address);

            switch (type)
            {
                case PLCType.BOOL:
                    return adsClient.ReadAny(Handel,typeof(bool));
                case PLCType.BYTE:
                case PLCType.USINT:
                    return (adsClient.ReadAny(Handel, typeof(byte)));
                case PLCType.WORD:
                case PLCType.UINT:
                    return (adsClient.ReadAny(Handel, typeof(ushort)));
                case PLCType.DWORD:
                case PLCType.UDINT:
                    return (adsClient.ReadAny(Handel, typeof(uint)));
                case PLCType.SINT:
                    return (adsClient.ReadAny(Handel, typeof(sbyte)));
                case PLCType.INT:
                    return (adsClient.ReadAny(Handel, typeof(short)));
                case PLCType.DINT:
                    return (adsClient.ReadAny(Handel, typeof(int)));
                case PLCType.LINT:
                    return (adsClient.ReadAny(Handel, typeof(long)));
                case PLCType.ULINT:
                    return (adsClient.ReadAny(Handel, typeof(ulong)));
                case PLCType.REAL:
                    return (adsClient.ReadAny(Handel, typeof(float)));
                case PLCType.LREAL:
                    return (adsClient.ReadAny(Handel, typeof(double)));
                case PLCType.STRING:
                    return (adsClient.ReadAny(Handel, typeof(string), new int[] {255}));
                default:
                    return null;
            }
        }
    }

    public enum PLCType
    {
        BOOL,
        BYTE,
        WORD,
        DWORD,
        SINT,
        INT,
        DINT,
        LINT,
        USINT,
        UINT,
        UDINT,
        ULINT,
        REAL,
        LREAL,
        STRING,
    }
}
